using System.Diagnostics;
using System.Text;

namespace TKH.BizTalk.Diagnostics
{
    /// <summary>
    /// 
    /// </summary>
    public class EventLogListener: System.Diagnostics.TraceListener
    {
        // Fields
        private EventLog eventLog;
        
        /// <summary>
        /// Constructor
        /// </summary>
        public EventLogListener()
        {
            this.eventLog = new System.Diagnostics.EventLog();
        }
        /// <summary>
        /// 
        /// </summary>
        public override void Close()
        {
            if (this.eventLog != null)
            {
                this.eventLog.Close();
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="disposing"></param>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                this.Close();
            }
        }

        private bool ValidEventLogSource(string source)
        {
            if (!EventLog.SourceExists(source))
            {
                EventLog.CreateEventSource(new EventSourceCreationData(source, "Application"));
            }
            this.eventLog.Source = source;
            return true;
        }
        private EventLogEntryType ConvertEventType(TraceEventType type)
        {
            switch (type)
            {
                case TraceEventType.Critical:
                case TraceEventType.Error:
                    return EventLogEntryType.Error;
                case TraceEventType.Warning:
                    return EventLogEntryType.Warning;
                default:
                    return EventLogEntryType.Information;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="eventCache"></param>
        /// <param name="source"></param>
        /// <param name="severity"></param>
        /// <param name="id"></param>
        /// <param name="data"></param>
        public override void TraceData(TraceEventCache eventCache, string source, TraceEventType severity, int id, params object[] data)
        {
            if (ValidEventLogSource(source) && severity <= TraceEventType.Warning)
            {
                StringBuilder builder = new StringBuilder();
                foreach (object item in data)
                {
                    builder.Append(item.ToString());
                    builder.Append("\n");
                }
                this.eventLog.WriteEntry(builder.ToString(), ConvertEventType(severity), id);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="eventCache"></param>
        /// <param name="source"></param>
        /// <param name="severity"></param>
        /// <param name="id"></param>
        /// <param name="data"></param>
        public override void TraceData(TraceEventCache eventCache, string source, TraceEventType severity, int id, object data)
        {
            if (ValidEventLogSource(source) && severity <= TraceEventType.Warning)
            {
                this.eventLog.WriteEntry(data.ToString(), ConvertEventType(severity), id);
                
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="eventCache"></param>
        /// <param name="source"></param>
        /// <param name="severity"></param>
        /// <param name="id"></param>
        /// <param name="message"></param>
        public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType severity, int id, string message)
        {
            if (ValidEventLogSource(source) && severity <= TraceEventType.Warning)
            {
                this.eventLog.WriteEntry(message, ConvertEventType(severity), id);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="eventCache"></param>
        /// <param name="source"></param>
        /// <param name="severity"></param>
        /// <param name="id"></param>
        /// <param name="format"></param>
        /// <param name="args"></param>
        public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType severity, int id, string format, params object[] args)
        {
            if (ValidEventLogSource(source) && severity <= TraceEventType.Warning)
            {
                this.eventLog.WriteEntry(string.Format(format, args), ConvertEventType(severity), id);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="message"></param>
        public override void Write(string message)
        {
            this.eventLog.WriteEntry(message, EventLogEntryType.Information);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="message"></param>
        public override void WriteLine(string message)
        {
            this.eventLog.WriteEntry(message + "\n", EventLogEntryType.Information);
        }
    }
}
